﻿//-----------------------------------------------------------------------
// <copyright file="RuleDescriptor.cs">
//     Copyright (c) Nicole Calinoiu. All rights reserved.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;

using Microsoft.FxCop.Sdk;
using Microsoft.VisualStudio.CodeAnalysis.Extensibility;

namespace Bordecal.FxCop.Sdk
{
	/// <summary>
	/// Base class for rule descriptors.
	/// </summary>
	public abstract class RuleDescriptor : IRuleDescriptor
	{
		#region Fields

		private readonly string _category;
		private readonly string _name;
		private readonly string _description;
		private readonly int _certainty;
		private readonly FixCategories _fixCategories;
		private readonly MessageLevel _messageLevel;
		private readonly string _checkId;
		private readonly string _owner;
		private readonly string _email;
		private readonly string _url;

		#endregion

		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="RuleDescriptor"/> class.
		/// </summary>
		/// <param name="category">The rule category.</param>
		/// <param name="name">The rule name.</param>
		/// <param name="description">The rule description.</param>
		/// <param name="checkId">The rule check ID.</param>
		/// <param name="owner">The rule owner.</param>
		/// <param name="email">The rule support e-mail address.</param>
		/// <param name="url">The rule help URL.</param>
		/// <param name="certainty">The default violation certainty.</param>
		/// <param name="fixCategories">The default fix categories.</param>
		/// <param name="messageLevel">The default message level.</param>
		protected RuleDescriptor(
			string category,
			string name,
			string description,
			string checkId,
			string owner,
			string email,
			Uri url,
			int certainty,
			FixCategories fixCategories,
			MessageLevel messageLevel)
		{
			if (category == null)
			{
				throw new ArgumentNullException("category");
			}

			if (name == null)
			{
				throw new ArgumentNullException("name");
			}

			if (description == null)
			{
				throw new ArgumentNullException("description");
			}

			if (checkId == null)
			{
				throw new ArgumentNullException("checkId");
			}

			if (owner == null)
			{
				throw new ArgumentNullException("owner");
			}

			if ((certainty < 0) || (certainty > 100))
			{
				throw new ArgumentOutOfRangeException("certainty", certainty, "The value must be between 0 and 100, inclusive.");
			}

			this._category = category;
			this._name = name;
			this._description = description;
			this._checkId = checkId;
			this._owner = owner;
			this._email = string.IsNullOrEmpty(email) ? "[none]" : email;
			this._url = (url == null) ? string.Empty : url.ToString();
			this._certainty = certainty;
			this._fixCategories = fixCategories;
			this._messageLevel = messageLevel;
		}

		#endregion

		#region Properties

		/// <summary>
		/// Gets the category under which the rule should appear in reports and the FxCop user interface.
		/// </summary>
		public string Category
		{
			get
			{
				return this._category;
			}
		}

		/// <summary>
		/// Gets the certainty that a reported problem is an actual violation of the rule.
		/// </summary>
		public int Certainty
		{
			get
			{
				return this._certainty;
			}
		}

		/// <summary>
		/// Gets the unique identifier for the rule.
		/// </summary>
		public string CheckId
		{
			get
			{
				return this._checkId;
			}
		}

		/// <summary>
		/// Gets a description of the rule.
		/// </summary>
		public string Description
		{
			get
			{
				return this._description;
			}
		}

		/// <summary>
		/// Gets the e-mail address to be used for support for the rule.
		/// </summary>
		public string Email
		{
			get
			{
				return this._email;
			}
		}

		/// <summary>
		/// Gets the <see cref="FixCategories"/> for violations of the rule.
		/// </summary>
		public FixCategories FixCategories
		{
			get
			{
				return this._fixCategories;
			}
		}

		/// <summary>
		/// Gets the <see cref="MessageLevel"/> for violations of the rule.
		/// </summary>
		public MessageLevel MessageLevel
		{
			get
			{
				return this._messageLevel;
			}
		}

		/// <summary>
		/// Gets the name of the rule.
		/// </summary>
		public string Name
		{
			get
			{
				return this._name;
			}
		}

		/// <summary>
		/// Gets the name of the rule owner.
		/// </summary>
		public string Owner
		{
			get
			{
				return this._owner;
			}
		}

		/// <summary>
		/// Gets the help URL for the rule.
		/// </summary>
		public string Url
		{
			get
			{
				return this._url;
			}
		}

		#endregion

		#region Methods

		/// <summary>
		/// Returns the resolution pattern string for a specified resoution.
		/// </summary>
		/// <param name="name">The resolution pattern name.</param>
		/// <returns>The resolution pattern string.</returns>
		public abstract string GetResolutionText(string name);

		#endregion
	}
}